﻿using System;

namespace Aiming.IteratorTasks
{
	public class TaskCompletionSource<TResult>
	{
		private Task<TResult> _task = new Task<TResult>(TaskStatus.Running);

		public Task<TResult> Task { get { return _task; } }

		public void SetCanceled()
		{
			((ITaskInternal)_task).Cancel();
		}

		public void SetException(Exception exception)
		{
			((ITaskInternal)_task).SetException(exception);
		}

		public void SetResult(TResult result)
		{
			((ITaskInternal)_task).SetResult(result);
		}

		// 外から SetResult とかされたくないので、internal なインターフェイスを作って、明示的実装。
		internal interface ITaskInternal
		{
			void Cancel();
			void SetException(Exception e);
			void SetResult(TResult result);
		}
	}

	public partial class Task<T> : TaskCompletionSource<T>.ITaskInternal
	{
		void TaskCompletionSource<T>.ITaskInternal.Cancel()
		{
			AddError(new TaskCanceledException());
			Complete();
		}

		void TaskCompletionSource<T>.ITaskInternal.SetException(Exception e)
		{
			AddError(e);
			Complete();
		}

		void TaskCompletionSource<T>.ITaskInternal.SetResult(T result)
		{
			_result = result;
			Complete();
		}
	}
}
